package myPackage;

import java.io.IOException;
import java.net.URI;
import java.util.logging.Level;

import net.Group.PrivatePeerGroup;
import net.Group.MembershipService.SecureCredential;
import net.jxta.document.AdvertisementFactory;
import net.jxta.endpoint.Message;
import net.jxta.endpoint.MessageElement;
import net.jxta.endpoint.StringMessageElement;
import net.jxta.peergroup.PeerGroup;
import net.jxta.pipe.PipeID;
import net.jxta.pipe.PipeMsgEvent;
import net.jxta.pipe.PipeMsgListener;
import net.jxta.pipe.PipeService;
import net.jxta.protocol.PipeAdvertisement;
import net.jxta.util.JxtaBiDiPipe;
import net.jxta.util.JxtaServerPipe;

public class SecurePipeServer {

	private transient PeerGroup netPeerGroup = null;
	private transient JxtaServerPipe serverPipe;
	private PrivatePeerGroup privatePeerGroup;
	private SecureCredential securecred;
	
    final static String MESSAGE_NAMESPACE_NAME = "SecurePipe";
    final static String MESSAGE_TYPE = "type";
    final static String MESSAGE_PEER_ID = "peer_id";
    final static String MESSAGE_ROLE_ID = "role_id";
    final static String MESSAGE_ROLE_CERT = "role_cert";
    
    final static String MESSAGE_ELEMENT_AUTHORIZATION_ROLE = "Authorization_role";
    final static String MESSAGE_ELEMENT_AUTHORIZATION_PERM = "Authorization_perm";
    final static String RESPONSE_ELEMENT_NAME = "response";
	
	//TO DO
	//the pipe need to be generated randomly for usage propose
	private final static PipeID SECURE_PIPEID = PipeID.create(URI.create("urn:jxta:uuid-59616261646162614E504720503250338944BCED387C4A2BBD8E9411B78C284104"));
	
	private SecurePipeServer(PrivatePeerGroup ppg)
	{
		this.privatePeerGroup = ppg;
		this.netPeerGroup = ppg.getPeerGroup();
		this.securecred = (SecureCredential)ppg.getFinalCredential();
		try{
		this.serverPipe = new JxtaServerPipe(this.netPeerGroup,getPipeAdvertisement());
		this.serverPipe.setPipeTimeout(0);
		}catch (Exception e){
			e.printStackTrace();
			return;
		}
	}    
	
	
	/**
	     * Gets the pipeAdvertisement attribute of the JxtaServerPipeExample class
	     *
	     * @return The pipeAdvertisement
	     */
	    public static PipeAdvertisement getPipeAdvertisement() {
	        PipeAdvertisement advertisement = (PipeAdvertisement)
	        AdvertisementFactory.newAdvertisement(PipeAdvertisement.getAdvertisementType());	        
	        advertisement.setPipeID(SECURE_PIPEID);
	        advertisement.setType(PipeService.UnicastSecureType);
	        advertisement.setName("Secure Pipe for authentication/authorization");
	        return advertisement;
	    }
	    
	    /**
	     * Connection wrapper. Once started, it sends ITERATIONS messages and
	     * receives a response from the initiator for each message.
	     */
	    private static class ConnectionHandler implements Runnable, PipeMsgListener {
	        private final JxtaBiDiPipe pipe;
	        private SecureCredential scred;
	        /**
	         * Constructor for the ConnectionHandler object
	         *
	         * @param pipe message pipe
	         */
	        ConnectionHandler(JxtaBiDiPipe pipe) {
	            this.pipe = pipe;
	            this.scred = (SecureCredential)pipe.getCredentialDoc();
	            pipe.setMessageListener(this);
	            
	        }
	        
	        /**
	         * {@inheritDoc}
	         */
	        public void pipeMsgEvent(PipeMsgEvent event) {
	            
	            try {
	                // grab the message from the event
	                Message msg = event.getMessage();
	                String type = msg.getMessageElement(MESSAGE_NAMESPACE_NAME, MESSAGE_TYPE).toString();
	                
	                if(type != null) {
	                	System.out.println("Message Received, processing..");
	                	if(type == MESSAGE_ELEMENT_AUTHORIZATION_ROLE)
	                	{
	                		String peer_id = msg.getMessageElement(MESSAGE_NAMESPACE_NAME, MESSAGE_PEER_ID).toString();
	                	}

	                }
	                else
	                	{
	                	System.out.println("Missing message element");
	                    return;
	                    }
	                
	                // System.out.println("Got Message :" + msgElement.toString());
	            } catch (Exception e) {
//	                if (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) {
//	                    LOG.log(Level.WARNING, "[" + Thread.currentThread().getName() + "] Failure during message receipt.", e);
	            	System.out.println("Failure during message receipt."+e);
	            }
	            }
	        
	        /**
	         * Send a series of messages over a pipe
	         *
	         * @param pipe the pipe to send messages over
	         * @throws IOException Thrown for errors sending messages.
	         */
	        private void sendMessages(JxtaBiDiPipe pipe, Message msg) throws IOException 
	        {
	   	                
	                System.out.println("[ Message Sending ] :" + msg.toString());
	                pipe.sendMessage(msg);
	        }
	        
	        //build message of the role request
	        
	        private Message buildRoleRequestMsg()
	        {
	        	Message msg = new Message();
	        	
	        	return msg;
	        }
	        
	        /**
	         * Main processing method for the ConnectionHandler object
	         */
	        public void run() {
	            try {
	                //sendMessages(pipe,msg);
	                System.out.println("[" + Thread.currentThread().getName() + "] Closing the pipe");
	                pipe.close();
	            } catch (Throwable all) {
	                //LOG.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] Failure in ConnectionHandler", all);
	            }
	        }
	    }
	
	   public void run()
	   {
		   System.out.println("Waiting for Secure Connection on SecurePipe");
		   while(true)
		   {
			   try{
				   JxtaBiDiPipe bipipe = serverPipe.accept();
				   Thread thread = new Thread(new ConnectionHandler(bipipe), "Connection Handler Thread");
				   thread.start();
			   }
			   catch(Exception e){
				   e.printStackTrace();
				   return;
			   }
		   }
	   }
}
	        
	
